package pl.edu.agh.gronoMining.frequentSubgraphFinder.parsers.strategy;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;

import pl.edu.agh.gronoMining.frequentSubgraphFinder.strategy.SimpleStrategyImpl;
import pl.edu.agh.gronoMining.frequentSubgraphFinder.strategy.Strategy;

/**
 * Parser of simple strategy files. Strategy file can contain lines: 
 * <br />
 * <code>startType: {type}</code> // {type} is the start node type. File must contain one and only one this line.<br />
 * <code>{fromType} -> {toType} : {rule}</code> // represents one rule which will by used when subgraph will be trying to 
 * add to node which type equals {fromType} new edge that connects this node to node witch type {toType}.
 * <br /><br />
 * {rule} is an integer than can be:<br />
 * 0 - extend <br />
 * >0 - don't extend <br />
 * <0 - extend, but with limited steps number <br />
 * <br />
 * Example: <br />
 * <code>
 * startType: 1<br />
 * 1 -> 2 : 0<br />
 * 2 -> 3 : 3<br />
 * 1 -> 3 : -1<br />
 * 2 -> 1 : 0<br />
 * </code> 
 */

public class StrategyParserImpl implements StrategyParser {

	@Override
	public Strategy parse(File f) throws ParseException {
		Strategy strategy = new SimpleStrategyImpl();
		
		int lineNo = 1;
		
		try {
			
			BufferedReader br = new BufferedReader(new FileReader(f));
			String line;
			
			while ((line = br.readLine()) != null) {
				
				line = line.trim();
				if (! "".equals(line)) {
					
					String[] lineParts = line.split("#");
					
					String[] lineData = lineParts[0].split(":");
					if (lineData.length != 2)
						throw new ParseException("Parse error", lineNo);
					else {
					
						String lineKey = lineData[0].trim();
						String lineValue = lineData[1].trim();
						
						if ("startType".equals(lineKey)) {
							
							int type = Integer.parseInt(lineValue);
							strategy.setStartType(type);
							
						} else {
							
							String[] ruleTypes = lineKey.split("->");
							
							if (ruleTypes.length != 2)
								throw new ParseException("Parse error", lineNo);
							else {
							
								String typeFromString = ruleTypes[0].trim();
								String typeToString = ruleTypes[1].trim();
							
								int typeFrom = Integer.parseInt(typeFromString);
								int typeTo = Integer.parseInt(typeToString);
							
								int rule = Integer.parseInt(lineValue);
							
								strategy.addStrategyRule(typeFrom, typeTo, rule);
								
							}
						}
					}
				}
				lineNo++;
				
			}
			
		} catch (IOException e) {
			throw new ParseException("File "+f.getAbsolutePath()+" not found", 1);
		} catch (NumberFormatException e) {
			throw new ParseException("Argument is not integer", lineNo);
		}
		
		return strategy;
	}

}
